import {
	doesFileExist,
	downLoadFile,
	downLoadTempObject,
	downLoadThumbnail,
	putObject,
	uploadPart,
} from "./request";
import { FileInfo } from "@/type";
import { IClient } from ".";
import { getFileMD5 } from "../fileHelper";

export default class FileOSS implements IClient {
	private libraryRoot: string;
	private libraryBucket: string;
	private maxFileSize?: number;
	constructor(
		libraryRoot: string,
		libraryBucket: string,
		maxFileSize?: number
	) {
		this.libraryRoot = libraryRoot;
		this.libraryBucket = libraryBucket;
		this.maxFileSize = maxFileSize;
	}

	upload(file: File, fileFullPath: string) {
		return new Promise<{ fileId: string }>(async (reslove, reject) => {
			try {
				if (this.maxFileSize && file.size > this.maxFileSize) {
					let fileId = await this.partUpload(file, fileFullPath);
					reslove({ fileId });
				} else {
					let info: FileInfo;
					// 简单文件上传
					let formData = new FormData();
					formData.append("file", file);
					try {
						info = await putObject<FileInfo>(
							this.libraryBucket,
							fileFullPath,
							formData
						);
					} catch (error) {
						reject(error);
					}
					reslove({ fileId: info!.id });
				}
			} catch (error) {
				reject(error);
			}
		});
	}
	async partUpload(file: File, fileFullPath: string) {
		return new Promise<string>(async (reslove, reject) => {
			try {
				// 总片数
				let totalNumber = Math.ceil(file.size / this.maxFileSize!);
				let index = 0;
				let md5 = await getFileMD5(file);
				while (index < totalNumber) {
					let formData = new FormData();
					formData.append(
						"file",
						file.slice(
							index * this.maxFileSize!,
							(index + 1) * this.maxFileSize!
						)
					);
					let info = await uploadPart<FileInfo>(
						this.libraryBucket,
						fileFullPath,
						md5,
						index + 1,
						totalNumber,
						formData
					);
					if (info.complete) {
						reslove(info.id);
					}
					index++;
				}
			} catch (error) {
				reject(error);
			}
		});
	}
	download(fileFullName: string, isOriginal?: boolean) {
		return new Promise<string>(async (reslove, reject) => {
			try {
				if (isOriginal) {
					// 原图
					let stream = await downLoadFile<Blob>(
						this.libraryBucket,
						fileFullName
					);
					reslove(window.URL.createObjectURL(stream));
				} else {
					let stream = await downLoadThumbnail<Blob>(
						fileFullName,
						this.libraryBucket
					);
					reslove(window.URL.createObjectURL(stream));
				}
			} catch (error) {
				reject(error);
			}
		});
	}
	downloadStream(fileFullName: string) {
		return new Promise<Blob>(async (reslove, reject) => {
			try {
				let stream = await downLoadFile<Blob>(this.libraryBucket, fileFullName);
				reslove(stream);
			} catch (error) {
				reject(error);
			}
		});
	}
	downloadZip(fileFullName: string, fileName: string) {
		return new Promise<string>(async (reslove, reject) => {
			try {
				const iframe = document.createElement("iframe");
				iframe.setAttribute("hidden", "hidden");
				document.body.appendChild(iframe);
				iframe.onload = () => {
					if (iframe) {
						iframe.setAttribute("src", "about:blank");
					}
				};
				iframe.setAttribute(
					"src",
					`${window.baseUrl}/TempFileStore/${fileFullName}`
				);
				reslove("");
			} catch (error) {
				reject(error);
			}
		});
	}
	isExist(fileFullName: string) {
		return new Promise<boolean>(async (reslove, reject) => {
			try {
				let response = await doesFileExist<{ exist: boolean }>(
					this.libraryBucket,
					fileFullName
				);
				reslove(response.exist);
			} catch (error) {
				reject(error);
			}
		});
	}
}
